package value_object.data;
import java.util.ArrayList;
import java.util.List;
import util.fraction;
import value_object.SolutionVO;

public class Request {

	private int request_index;
	private float request_surface;
	private int request_gain;
	private int request_type;
	private int request_stereo;
	
	private List<Strip> stripList;
	
	//Default constructor
	public Request() {
		stripList = new ArrayList<Strip>();
	}
	
	public void addAStrip(Strip strip) {
		stripList.add(strip);
	}
	
	public void setStripList(List<Strip> stripList) {
		this.stripList = stripList;
	}
	
	public List<Strip> getStripList() {
		return stripList;
	}
	
	/*
	 * Getters and setters
	 */
	public int getRequest_index() {
		return request_index;
	}

	public void setRequest_index(int request_index) {
		this.request_index = request_index;
	}

	public float getRequest_surface() {
		return request_surface;
	}

	public void setRequest_surface(float request_surface) {
		this.request_surface = request_surface;
	}

	public int getRequest_gain() {
		return request_gain;
	}

	public void setRequest_gain(int request_gain) {
		this.request_gain = request_gain;
	}

	public int getRequest_type() {
		return request_type;
	}

	public void setRequest_type(int request_type) {
		this.request_type = request_type;
	}

	public int getRequest_stereo() {
		return request_stereo;
	}

	public void setRequest_stereo(int request_stereo) {
		this.request_stereo = request_stereo;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		
		buffer.append(this.request_index + "(request-index)");
		buffer.append(" ");
		buffer.append(this.request_gain + "(request-gain)");
		buffer.append(" ");
		buffer.append(this.request_surface + "(request-surface)");
		buffer.append(" ");
		buffer.append(this.request_type + "(request-type)");
		buffer.append(" ");
		buffer.append(this.request_stereo + "(request-stereo)");
		
		return buffer.toString();
	}
	
	public String toSimpleString() {
		StringBuffer buffer = new StringBuffer();
		
		buffer.append(this.request_index);
		buffer.append(" ");
		buffer.append(this.request_gain);
		buffer.append(" ");
		buffer.append(this.request_surface);
		buffer.append(" ");
		buffer.append(this.request_type);
		buffer.append(" ");
		buffer.append(this.request_stereo);
		
		return buffer.toString();
	}
	
	/**
	 * Calculate the gain of a query (both normal and polygon)
	 * 
	 * @param aStrip
	 * @return gain
	 */
	public double calculateGain(Strip aStrip){
		//normal request
		if(request_type == 0)
			return calculateGainOfNormal(aStrip);
		
		//polygone request
		if(request_type == 2)
			return calculateGainOfPolygon(aStrip);
		
		return 0;
	}
	
	/**
	 * Calculate the gain of a strip (for request_type = 0) => normal strip
	 * 
	 * @param aStrip
	 * @return gain
	 */
	private double calculateGainOfNormal(Strip aStrip) {
		if(request_stereo == 0) //request is mono
			return request_gain * aStrip.getStrip_surface();
		
		if(request_stereo == 1) //request is stereo
			return request_gain * aStrip.getStrip_surface() * 2;
		
		return 0;
	}
	
	/**
	 *  Calculate the gain of the query polygon type
	 *  
	 * @param aStrip
	 * @return
	 */
	public double calculateGainOfPolygon(Strip aStrip){
		double gain = 0;
		
		System.out.println("aStrip.getStrip_surface() = "+ aStrip.getStrip_surface());
		System.out.println("request_surface = "+ request_surface);
		System.out.println("request_gain = "+ request_gain);
		
		if(request_stereo == 0) //request is mono
			gain += request_gain * request_surface * gainOfPartialAcquisitionPolygon(aStrip);
		else
			gain += request_gain * request_surface * 2 * gainOfPartialAcquisitionPolygon(aStrip);
		
		return gain;	
	}	 

	
	/**
	 * This method allows for the portion acquired a strip of type polygon
	 * 
	 * @param aStrip
	 * @return
	 */
	public double gainOfPartialAcquisitionPolygon(Strip aStrip){
		double fractionvalue = 0;
		double result = 0;
		
		if(request_stereo == 0) // request is mono
			fractionvalue = aStrip.getStrip_surface() / request_surface;
		 if (request_stereo == 1) // request is stereo
			fractionvalue = aStrip.getStrip_surface() / (2*request_surface);
		
		if (fractionvalue >= 0 && fractionvalue <= 0.4)
			result = fraction.gainOfPartialAcquisition(1, fractionvalue);
		if (fractionvalue > 0.4 && fractionvalue < 0.7)
			result = fraction.gainOfPartialAcquisition(2, fractionvalue);
		if (fractionvalue >= 0.7 && fractionvalue <= 1)
			result = fraction.gainOfPartialAcquisition(3, fractionvalue);
		return result;
	}
	
	
	
   /**
    * Get a list of strips from solution file
    * 
    * @param solution
    * @return
    */
	public List<Strip> getStripListFrom(SolutionVO solution) {
		List<Strip> solutionStripList = new ArrayList<Strip>();
		
		List<Acquisition> acqList = solution.getAcquisitionList();
		
		for (int i = 0; i < acqList.size(); i++) {
			int strip_index = acqList.get(i).getStrip_index();
			Strip strip = getStripByIndex(strip_index, this.getStripList());
			
			if (strip != null) {
				solutionStripList.add(strip);
			}
		}
		
		return solutionStripList;
	}
	
	/**
	 * Get a strip from a strip list
	 * 
	 * @param strip_index
	 * @param stripList
	 * @return
	 */
	private Strip getStripByIndex(int strip_index, List<Strip> stripList) {
		for (int i = 0; i < stripList.size(); i++) {
			if (stripList.get(i).getStrip_index() == strip_index)
				return stripList.get(i);
		}
		return null;
	}
}
